<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    当一个非boolean值被强制转换为一个boolean时，它是变成true还是false。 在JavaScript中“falsy”的明确列表如下： "" （空字符串） 0, -0, NaN （非法的number） null, undefined false
    任何不在这个“falsy”列表中的值都是“truthy”。这是其中的一些例子： "hello" 42 true [ ], [ 1, "2", 3 ] （数组） { }, { a: 42 } （对象） function foo() { .. } （函数）
    重要的是要记住，一个非boolean值仅在实际上被强制转换为一个boolean时才遵循这个“truthy”/“falsy”强制转换 var a = "42"; var b = 42; a == b; // true 强制转换 a === b; // false 在a ==
    b的比较中，JS注意到类型不匹配，于是它经过一系列有顺序的步骤将一个值或者它们两者强制转换为一个不同的类型，直到类型匹配为止，然后就可以检查一个简单的值等价性
    如果一个比较的两个值之一可能是true或false值，避免==而使用===。 如果一个比较的两个值之一可能是这些具体的值（0，""，或[] —— 空数组），避免==而使用===。 在 所有
    其他情况下，你使用==是安全的。它不仅安全，而且在许多情况下它可以简化你的代码并改善可读性。 函数作用域
    你使用var关键字声明的变量将属于当前的函数作用域，如果声明位于任何函数外部的顶层，它就属于全局作用域 提升
    无论var出现在一个作用域内部的何处，这个声明都被认为是属于整个作用域，而且在作用域的所有位置都是可以访问的。 这种行为称为 提升，比喻一个var声明在概念上 被移动
    到了包含它的作用域的顶端。技术上讲，这个过程通过代码的编译方式进行解释更准确，
    <script>
      age = prompt('Please tell me your age:')
      console.log(age)

      /*       函数
      另一个你将在JS程序中到处使用的object子类型是函数： */

      function foo() {
        return 42
      }

      foo.bar = 'hello world'

      typeof foo // "function"
      typeof foo() // "number"
      typeof foo.bar // "string"
      // 同样地，函数也是object的子类型 —— typeof返回"functio

      function makeAdder(x) {
        // 参数 `x` 是一个内部变量
        // 内部函数 `add()` 使用 `x`，所以它对 `x` 拥有一个“闭包”
        function add(y) {
          return y + x
        }

        return add
      }
    </script>

    <script>
      var foo = {
        a: 42
      }

      // 创建 `bar` 并将它链接到 `foo`
      var bar = Object.create(foo)
      console.log(bar)
      bar.b = 'hello world'

      bar.b // "hello world"
      bar.a // 42 <-- 委托到 `foo`
    </script>
  </body>
</html>
